package cn.iocoder.yudao.module.contract.service.order;

import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import cn.iocoder.yudao.module.contract.controller.admin.exportContract.vo.ExportOrderPageReqVO;
import cn.iocoder.yudao.module.contract.dal.dataobject.frameworkAgreement.FrameworkAgreementDO;
import cn.iocoder.yudao.module.contract.dal.mysql.frameworkAgreement.FrameworkAgreementMapper;
import cn.iocoder.yudao.module.contract.enums.OrderShippingStatusEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import cn.iocoder.yudao.module.contract.controller.admin.order.vo.*;
import cn.iocoder.yudao.module.contract.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.contract.dal.dataobject.order.OrderDetailsDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.contract.dal.mysql.order.OrderMapper;
import cn.iocoder.yudao.module.contract.dal.mysql.order.OrderDetailsMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.contract.enums.ErrorCodeConstants.*;

/**
 * 订单 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class OrderServiceImpl extends ServiceImpl<OrderMapper, OrderDO> implements OrderService {

    @Resource
    private OrderMapper orderMapper;
    @Resource
    private OrderDetailsMapper orderDetailsMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createOrder(OrderSaveReqVO createReqVO) {
        // 插入
        OrderDO order = BeanUtils.toBean(createReqVO, OrderDO.class);
        orderMapper.insert(order);

        // 插入子表
        createOrderDetailsList(order.getId(), createReqVO.getOrderDetailss());
        // 返回
        return order.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrder(OrderSaveReqVO updateReqVO) {
        // 校验存在
        validateOrderExists(updateReqVO.getId());
        // 更新
        OrderDO updateObj = BeanUtils.toBean(updateReqVO, OrderDO.class);
        orderMapper.updateById(updateObj);

        // 更新子表
        updateOrderDetailsList(updateReqVO.getId(), updateReqVO.getOrderDetailss());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteOrder(Long id) {
        // 校验存在
        validateOrderExists(id);
        // 删除
        orderMapper.deleteById(id);

        // 删除子表
        deleteOrderDetailsByOrderId(id);
    }

    private void validateOrderExists(Long id) {
        if (orderMapper.selectById(id) == null) {
            throw exception(ORDER_NOT_EXISTS);
        }
    }

    @Override
    public OrderDO getOrder(Long id) {
        return orderMapper.selectById(id);
    }

    @Override
    public PageResult<OrderDO> getOrderPage(OrderPageReqVO pageReqVO) {
        return orderMapper.selectPage(pageReqVO);
    }

    // ==================== 子表（订单明细） ====================

    @Override
    public List<OrderDetailsDO> getOrderDetailsListByOrderId(Long orderId) {
        return orderDetailsMapper.selectListByOrderId(orderId);
    }

    @Override
    public IPage<OrderDetailsRespVO> getOrderDetailsPage(OrderDetailsPageReqVO reqVO) {
        QueryWrapper<OrderDetailsPageReqVO> wrapperX = new QueryWrapperX<OrderDetailsPageReqVO>()
                .eq("o.deleted",0)
                .eqIfPresent("o.audat", reqVO.getAudat())
                .likeIfPresent("o.vbeln", reqVO.getVbeln())
                .likeIfPresent("o.vkorg", reqVO.getVkorg())
                .betweenIfPresent("o.create_time", reqVO.getCreateTime())
                .and(!ObjectUtils.isEmpty(reqVO.getPzinfo()), i -> i.like("o.auart", reqVO.getPzinfo()).or().like("o.auartt", reqVO.getPzinfo()))
                .and(!ObjectUtils.isEmpty(reqVO.getBuinfo()),i -> i.like("o.bukrs", reqVO.getBuinfo()).or().like("o.butxt", reqVO.getBuinfo()))
                .and(!ObjectUtils.isEmpty(reqVO.getKuinfo()),i -> i.like("o.kunnr", reqVO.getKuinfo()).or().like("o.kname", reqVO.getKuinfo()))
                .and(!ObjectUtils.isEmpty(reqVO.getVkinfo()),i -> i.like("o.vkbur", reqVO.getVkinfo()).or().like("o.vkburt", reqVO.getVkinfo()))
                .and(!ObjectUtils.isEmpty(reqVO.getVkginfo()),i -> i.like("o.vkgrp", reqVO.getVkginfo()).or().like("o.vkgrpt", reqVO.getVkginfo()))
                .and(!ObjectUtils.isEmpty(reqVO.getYwyinfo()),i -> i.like("o.ywy", reqVO.getYwyinfo()).or().like("o.ywyt", reqVO.getYwyinfo()))
                .orderByDesc("o.audat").orderByDesc("o.vbeln");
        IPage<OrderDetailsPageReqVO> page = new Page<OrderDetailsPageReqVO>(reqVO.getPageNo(), reqVO.getPageSize());
        return orderDetailsMapper.selectOrderDetailsPage(page,wrapperX);
    }

    @Override
    public PageResult<OrderDO> getExportOrderPage(ExportOrderPageReqVO pageReqVO) {
        return orderMapper.getExportOrderPage(pageReqVO);
    }

    @Override
    public List<OrderDO> listUnShippingOrders() {
        LambdaQueryWrapper<OrderDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderDO::getShipmentStatus, OrderShippingStatusEnum.UN_SHIPPING);
        return list(queryWrapper);
    }

    @Override
    public boolean updateOrderShippingStatus(String vbeln, String latestShipmentDate,String completeState,String completeStateExplain) {
        return orderMapper.updateOrderShippingStatus(vbeln,latestShipmentDate,completeState,completeStateExplain) > 0;
    }

    @Override
    public List<OrderDetailsDO> getOrderMoneyById(long orderId) {
        return orderDetailsMapper.getOrderMoneyById(orderId);
    }

    private void createOrderDetailsList(Long orderId, List<OrderDetailsDO> list) {
        list.forEach(o -> o.setOrderId(orderId));
        orderDetailsMapper.insertBatch(list);
    }

    private void updateOrderDetailsList(Long orderId, List<OrderDetailsDO> list) {
        deleteOrderDetailsByOrderId(orderId);
		list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下：1）id 冲突；2）updateTime 不更新
        createOrderDetailsList(orderId, list);
    }

    private void deleteOrderDetailsByOrderId(Long orderId) {
        orderDetailsMapper.deleteByOrderId(orderId);
    }

}